using System;
using System.Collections.Generic;
using System.Text;
using MathNet.Numerics.LinearAlgebra;

namespace igather.Framework
{
    public interface IGraph
	{		
        /// <summary>
        /// Adds a vertex to this graph
        /// </summary>
        /// <param name="v">Vertex to add</param>
        void AddVertex(Vertex v);

        /// <summary>
        /// Finds a vertex in the graph
        /// </summary>
        /// <param name="v">Vertex to find</param>
        /// <returns>The vertex if it is found, otherwise null</returns>
        Vertex GetVertex(Vertex v);

        /// <summary>
        /// Removes a vertex from the graph
        /// </summary>
        /// <param name="v">Vertex to remove</param>
        /// <returns>True if vertex was removed, otherwise false</returns>
        bool RemoveVertex(Vertex v);

        /// <summary>
        /// Gets the list of edges for a vertex
        /// </summary>
        /// <param name="v">Vertex to get the edges from</param>
        /// <returns>The list of edges for a vertex</returns>
        List<Edge> GetEdges(Vertex v);

        /// <summary>
        /// Gets the list of vertices in this graph
        /// </summary>
        List<Vertex> Vertices { get; }

        /// <summary>
        /// True if this graph is directed, otherwise false
        /// </summary>
        bool IsDirected { get; }

        /// <summary>
        /// Creates a new edge from this graph
        /// </summary>
        /// <param name="head">Head vertex for this edge</param>
        /// <param name="tail">Tail vertex for this edge</param>
        /// <returns>An instance of the Edge class</returns>
        Edge CreateEdge(Vertex head, Vertex tail);

        /// <summary>
        /// Creates a new edge from this graph
        /// </summary>
        /// <param name="head">Head vertex for this edge</param>
        /// <param name="tail">Tail vertex for this edge</param>
        /// <param name="weight">Weight of the edge</param>
        /// <returns>An instance of the Edge class</returns>
        Edge CreateEdge(Vertex head, Vertex tail, double weight);

        /// <summary>
        /// Adds an edge to this graph
        /// </summary>
        /// <param name="e">Edge to add</param>
        void AddEdge(Edge e);

        /// <summary>
        /// Finds an edge in this graph
        /// </summary>
        /// <param name="e">Edge to find</param>
        /// <returns>The edge if it is found, otherwise null</returns>
        Edge GetEdge(Edge e);

        /// <summary>
        /// Removes an edge from the graph
        /// </summary>
        /// <param name="e">Edge to remove</param>
        /// <returns>True if edge was removed, otherwise false</returns>
        bool RemoveEdge(Edge e);

        /// <summary>
        /// Gets the list of edges with at least one node in this graph
        /// </summary>
        List<Edge> Edges { get; }
		
		/// <summary>
		/// Creates a matrix that represents this graph 
		/// </summary>
		/// <returns>
		/// A matrix representation of this graph
		/// </returns>
		Matrix ToMatrix();
		
		/// <summary>
		/// Creates a string representation of this graph 
		/// </summary>
		/// <remarks>
		/// The format used here is GraphViz's
		/// http://www.graphviz.org/
		/// </remarks>
		/// <returns>
		/// A string repreentation of this graph
		/// </returns>
		string ToString();
    }
}
